package com.ygqh.baby.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.ygqh.baby.ao.CodeType;
import com.ygqh.baby.ao.DataStatus;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.OrderStatus;
import com.ygqh.baby.ao.QueryInfo;
import com.ygqh.baby.ao.ResultSet;
import com.ygqh.baby.mapper.KsdOrderMapper;
import com.ygqh.baby.model.BaseSkuInfo;
import com.ygqh.baby.model.YgShoppingCarModel;
import com.ygqh.baby.po.KsdOrder;
import com.ygqh.baby.po.KsdOrderDetail;
import com.ygqh.baby.po.KsdOrderExample;
import com.ygqh.baby.po.KsdStock;
import com.ygqh.baby.po.YgOrderPayment;
import com.ygqh.baby.service.KsdOrderDetailService;
import com.ygqh.baby.service.KsdOrderService;
import com.ygqh.baby.service.KsdStockService;
import com.ygqh.baby.service.WxMpAuthorityService;
import com.ygqh.baby.service.WxMpMessageService;
import com.ygqh.baby.service.YgFrameCodeService;
import com.ygqh.baby.service.YgOrderPaymentService;
import com.ygqh.baby.service.YgShoppingCarService;

@Service
public class KsdOrderServiceImpl implements KsdOrderService {

	@Autowired
	private KsdOrderMapper ksdOrderMapper;
	@Autowired
	private KsdStockService ksdStockService;
	@Autowired
	private YgShoppingCarService shoppingCarService;
	@Autowired
	private YgFrameCodeService ygFrameCodeService;
	@Autowired
	private KsdOrderDetailService ksdOrderDetailService;
	@Autowired
	private YgOrderPaymentService ygOrderPaymentService;
	@Autowired
	private WxMpMessageService wxMpMessageService;
	@Autowired
	private WxMpAuthorityService wxMpAuthorityService;

	@Override
	public List<KsdOrder> find() {
		KsdOrderExample example = new KsdOrderExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ksdOrderMapper.selectByExample(example);
	}

	@Override
	public int findCount() {
		KsdOrderExample example = new KsdOrderExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ksdOrderMapper.countByExample(example);
	}

	@Override
	public KsdOrder findById(Long id) {
		return ksdOrderMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(KsdOrder ksdOrder) {
		return ksdOrderMapper.insertSelective(ksdOrder);
	}

	@Override
	public int update(KsdOrder ksdOrder) {
		return ksdOrderMapper.updateByPrimaryKeySelective(ksdOrder);
	}

	@Override
	public int deleteSoft(Long[] ids) {
		Assert.notEmpty(ids);
		KsdOrderExample example = new KsdOrderExample();
		example.createCriteria().andIdIn(Arrays.asList(ids));
		KsdOrder record = new KsdOrder();
		record.setStatus(DataStatus.Delete);

		return ksdOrderMapper.updateByExampleSelective(record, example);
	}

	@Override
	public int deleteSoft(Long id) {
		return this.deleteSoft(new Long[] { id });
	}

	@Override
	public int saveOrUpdate(KsdOrder ksdOrder) {
		int r = 0;
		if (ksdOrder.getId() != null) {
			r = this.update(ksdOrder);
		} else {
			r = this.save(ksdOrder);
		}
		return r;
	}

	@Override
	public Message commitOrder(List<BaseSkuInfo> skuList) {

		List<YgShoppingCarModel> list = shoppingCarService.findItemInfo(skuList, 0L);
		List<String> skuCodes = new ArrayList<String>();

		Long orderId = ygFrameCodeService.getFrameCode(CodeType.Order, new Date());
		BigDecimal totalPrice = new BigDecimal("0.00");
		List<KsdOrderDetail> details = new ArrayList<KsdOrderDetail>();
		for (YgShoppingCarModel car : list) {
			BigDecimal salesPrice = car.getPromotionPrice().intValue() > 0 ? car.getPromotionPrice() : car.getSalesPrice();
			totalPrice = totalPrice.add(salesPrice.multiply(new BigDecimal(car.getQuantity())));

			KsdOrderDetail detail = new KsdOrderDetail(orderId, car.getProductId(), car.getSkuId(), car.getSkuCode(), salesPrice, car.getQuantity(), null);
			details.add(detail);
			skuCodes.add(car.getSkuCode());
		}
		// 校验库存
		List<KsdStock> stockList = ksdStockService.findStockBySkuCode(skuCodes, skuList.get(0).getSupplierId());
		Message msg = ksdStockService.checkStockNum(stockList, list);
		if (msg.getType().equals(Message.Type.error)) {
			return msg;
		}
		ksdStockService.checkStockNum(stockList, list);
		// 保存订单
		KsdOrder ksdOrder = new KsdOrder(orderId, skuList.get(0).getSupplierId(), orderId.toString(), totalPrice, OrderStatus.WaitingPay, null);

		this.save(ksdOrder);
		ksdOrderDetailService.saveDetailBatch(details);
		return Message.success(ksdOrder);
	}

	@Override
	public void paySuccess(String paymentCode, String transactionId, String openId, BigDecimal totalPrice) {
		YgOrderPayment payment = ygOrderPaymentService.findByPayCode(paymentCode);
		payment.setPaidPrice(totalPrice);
		payment.setPaySuccessTime(new Date());
		payment.setTransactionId(transactionId);
		// 回写订单状态
		KsdOrder order = this.findByOrderId(Long.parseLong(payment.getOrderId()));
		order.setOrderStatus(OrderStatus.TradeSuccess);
		order.setPayTime(payment.getPaySuccessTime());
		order.setOpenId(openId);
		this.updateByOrderId(order);

		// 扣减库存
		List<KsdOrderDetail> detailList = ksdOrderDetailService.findByOrderId(Long.parseLong(payment.getOrderId()));
		List<KsdStock> stockList = new ArrayList<KsdStock>();
		for (KsdOrderDetail detail : detailList) {
			KsdStock KsdStock = new KsdStock(order.getSupplierId(), detail.getSkuCode(), -detail.getQuantity());
			stockList.add(KsdStock);
		}
		ksdStockService.updateStockBatch(stockList);
		// 回写流水状态
		ygOrderPaymentService.writeBackPayment(payment);
		wxMpMessageService.sendOrderPaySuccessMsg("亲，您的订单已支付成功。", order.getOrderId(), openId, totalPrice, detailList.get(0).getProductName(), detailList.size(),
				"http://m.yiigoo.com/popupstore/orderdetail.html?orderId=" + order.getOrderId());
	}

	@Override
	public int updateByOrderId(KsdOrder ksdOrder) {
		KsdOrderExample example = new KsdOrderExample();
		example.createCriteria().andOrderIdEqualTo(ksdOrder.getOrderId());

		return ksdOrderMapper.updateByExampleSelective(ksdOrder, example);
	}

	@Override
	public int writeBackOpenId(String openId, Long orderId) {
		KsdOrder ksdOrder = new KsdOrder(orderId, openId);
		return this.updateByOrderId(ksdOrder);
	}

	@Override
	public KsdOrder findByOrderId(Long orderId) {
		KsdOrderExample example = new KsdOrderExample();
		example.createCriteria().andOrderIdEqualTo(orderId);
		List<KsdOrder> list = ksdOrderMapper.selectByExample(example);
		if (!CollectionUtils.isEmpty(list)) {
			return list.get(0);
		}
		return null;
	}

	@Override
	public ResultSet<KsdOrder> search(QueryInfo queryInfo, String q, Date startDate, Date endDate, OrderStatus orderStatus) {
		List<KsdOrder> list = ksdOrderMapper.selectSuper(queryInfo, q, startDate, endDate, orderStatus);
		int count = ksdOrderMapper.countSuper(q, startDate, endDate, orderStatus);
		ResultSet<KsdOrder> resultSet = new ResultSet<KsdOrder>(count, list);
		return resultSet;
	}

	@Override
	public List<Map<String, Object>> findOrderDetail(Long orderId) {
		return ksdOrderMapper.findOrderDetail(orderId);
	}

	@Override
	public List<Map<String, Object>> getOrderReport(Date startDate, Date endDate, OrderStatus orderStatus) {
		return ksdOrderMapper.findOrderReport(null, startDate, endDate, orderStatus);
	}

}
